package main

import (
	"bytes"
	"crypto/sha256"
	"fmt"
)

type Blockchain struct {
	Blocks []*Block
}

type Block struct {
	Hash     []byte
	Data     []byte
	PrevHash []byte
}

func (b *Block) DeriveHash() {
	// 无符号拼接数据
	info := bytes.Join([][]byte{b.Data, b.PrevHash}, []byte{})
	// 计算哈希
	hash := sha256.Sum256(info)
	// 赋值给Block
	b.Hash = hash[:]
}
func CreateBlock(data string, prevHash []byte) *Block {
	block := &Block{[]byte{}, []byte(data), prevHash}
	block.DeriveHash()
	return block
}
func (chain *Blockchain) AddBlock(data string) {
	prevBlock := chain.Blocks[len(chain.Blocks)-1]
	new := CreateBlock(data, prevBlock.Hash)
	chain.Blocks = append(chain.Blocks, new)
}

// Genesis 创建创世块
func Genesis() *Block {
	return CreateBlock("Genesis", []byte{})
}
func InitBlockchain() *Blockchain {
	return &Blockchain{[]*Block{Genesis()}}
}
func main() {
	chain := InitBlockchain()
	chain.AddBlock("Send 1 BTC to Ivan")
	chain.AddBlock("Send 2 more BTC to Ivan")
	chain.AddBlock("Send 3 BTC to Ivan")
	for _, block := range chain.Blocks {
		fmt.Printf("Prev. hash: %x\n", block.PrevHash)
		fmt.Printf("Data: %s\n", block.Data)
		fmt.Printf("Hash: %x\n", block.Hash)
	}

}
